unit createnew;

{$mode objfpc}{$H+}

interface

uses
  Classes, SysUtils, LResources, Forms, Controls, Graphics, Dialogs, ComCtrls,
  Menus, Buttons, DOM, XMLWrite;

type

  { TfrmCreateNew }
  
  TNodeData = class
            nBalance : Single;
  end;

  TfrmCreateNew = class(TForm)
    cmdSave: TButton;
    lvwCreate: TListView;
    mnuDelete: TMenuItem;
    mnuNew: TMenuItem;
    popCreate: TPopupMenu;
    tvwCreate: TTreeView;

    procedure cmdSaveClick(Sender: TObject);
    procedure FormCreate(Sender: TObject);
    procedure mnuDeleteClick(Sender: TObject);
    procedure mnuNewClick(Sender: TObject);
    procedure tvwCreateChange(Sender: TObject; Node: TTreeNode);
    procedure UpdateListView;
  private
    { private declarations }
  public
    { public declarations }
  end;

var
  frmCreateNew: TfrmCreateNew;


implementation

{ TfrmCreateNew }

procedure TfrmCreateNew.mnuNewClick(Sender: TObject);
var
   sText      : string;
   sInitial   : string;
begin

     // make sure an account is selected
     if (tvwCreate.Selected = nil ) then
     begin
          ShowMessage('Please select an account');
          Exit;
     end;

     InputQuery('Create new account','Enter name for the account',sText);
     InputQuery('Create new account','Enter initial balance',sInitial);
     // TODO: dont ask for income and expense acc
     
     // TODO: handle error for inital amount type
     with tvwCreate.Items.AddChild(tvwCreate.Selected,sText) do
     begin
          Data := TNodeData.Create ;
          TNodeData(Data).nBalance := single(StrToFloat(sInitial));
          MakeVisible;
     end;
     UpdateListView ;
end;

procedure TfrmCreateNew.tvwCreateChange(Sender: TObject; Node: TTreeNode);
begin
  UpdateListView;
end;


procedure TfrmCreateNew.mnuDeleteClick(Sender: TObject);
begin

     // make sure something is selected to delete
     if (tvwCreate.Selected = nil ) then
     begin
          ShowMessage('Please choose an account to delete');
          Exit;
     end;

     // dont delete the four basic account type
     if (tvwCreate.Selected.Level = 0 ) then
     begin
          ShowMessage('You cannot delete an account type');
          Exit;
     end;
     
     // free mem
     if tvwCreate.Selected.Data <> nil then
        TNodeData(tvwCreate.Selected.Data).Free ;
     tvwCreate.Selected.delete;
end;

procedure TfrmCreateNew.cmdSaveClick(Sender: TObject);
var
   sAsset : String;
   TreeNode : TTreeNode;

   tn : TTreeNode;
   XMLDoc : TXMLDocument;
   iNode,jNode : tdomnode;
   
    // recursin proc
    procedure ProcessTreeItem(
          tn    : TTreeNode;
          ixNode : tdomNode);
    var
      cNode : TDOMNode;
      e     : TDOMElement;
    begin
      if (tn = nil) then Exit;
      
      // one of the four basic types
      if (tn.Level=0) then
      begin
         cNode := XMLDoc.CreateElement(tn.text)
      end
      else
      begin
      	  cNode := XMLDoc.CreateElement('Account');
          e := cNode as TDOMElement;
          e['name'] := tn.Text;
          
          // show initial attr only for leaf nodes
          if (tn.HasChildren = false) then
          begin
               //str(TNodeData(tn.Data).nBalance,sasset);
               sAsset := FormatFloat('0.00',(TNodeData(tn.Data).nBalance));
               e['initial'] := sAsset;
          end;
      end;
      ixnode.AppendChild(cnode);

      //child nodes
      tn := tn.getFirstChild;
      while tn <> nil do
      begin
        ProcessTreeItem(tn, cNode);
        tn := tn.getNextSibling;
      end;
    end; (*ProcessTreeItem*)

begin

     // TODO: Make efficient
     // do an update so all tree view .data are set.
     TreeNode := tvwCreate.Items.GetFirstNode;
     while TreeNode<>nil do
     begin
     	   TreeNode.Selected := true;
     	   UpdateListView;
       	   TreeNode.Selected := false;
       	   TreeNode := TreeNode.GetNextSibling;
     end;
     TreeNode := tvwCreate.Items.GetFirstNode;

     XMLDoc := TXMLDocument.Create;
     iNode   := XMLDoc.CreateElement('Sal');
     XMLDoc.AppendChild(iNode);
     jNode   := XMLDoc.CreateElement('Transactions');
     iNode.AppendChild(jNode);
     jNode   := XMLDoc.CreateElement('Accounts');
     iNode.AppendChild(jNode);


     tn := tvwCreate.TopItem;
     while tn <> nil do
     begin
     	  ProcessTreeItem (tn, jNode);
     	  tn := tn.getNextSibling;
     end;

     writeXMLFile(XMLdoc, 'accounts.sal');
     XMLDoc.Destroy;
     frmCreateNew.Close;
end;

procedure TfrmCreateNew.FormCreate(Sender: TObject);
begin
end;


procedure TfrmCreateNew.UpdateListView;
var
   ChildNode: TTreeNode;
   sText    : String;
begin
     lvwCreate.Clear ;

     // make sure something is selected
     if (tvwCreate.Selected=nil) then
        Exit;
        
     // the common 'one folder above' link
     if (tvwCreate.Selected.Parent <> nil) then
     begin
          with lvwCreate.items.add do
          begin
               Caption := 'To Parent(todo)';
               Data    := tvwCreate.Selected.Parent.Data ;
          end;
     end;

     // supposed to speed up processing - complemented by an endupdate
     tvwCreate.Items.BeginUpdate ;
     
     ChildNode := tvwCreate.Selected.GetFirstChild ;
     while (ChildNode <> nil) do
     begin
          with lvwCreate.Items.Add do
          begin
               Caption := ChildNode.Text;
               Data    := ChildNode.Data;

               // for default items, set balance=0;
               if (TNodeData(childnode.Data) = nil) then
               begin
                  ChildNode.Data := TNodeData.Create;
                  TNodeData(ChildNode.data).nBalance := 0.00;
               end;

               
       	       str(TNodeData(ChildNode.Data).nBalance:10:2,sText);

               // TODO: dont display for income and expense accounts
               // dont display amount is it has further children
               if (ChildNode.HasChildren) then
                  sText := 'Have subaccounts';
               SubItems.Add(sText);
               sText := ChildNode.GetParentNodeOfAbsoluteLevel(0).Text ;
               SubItems.Add(sText);
          end;
          ChildNode := tvwCreate.Selected.GetNextChild(ChildNode);
     end;
     tvwCreate.Items.EndUpdate;

end;

initialization
  {$I createnew.lrs}

end.

